AWS Elastic BeanstalkのTomcatはyum updateで更新してはならない
旧タイトル:AWS Elastic BeanstalkのJava環境をRDSと同時起動した際にRDSのホスト名等がダブルクオートで囲まれる「ことがある」件
本件の原因は、Beanstalkのサーバに入って、無意識的にyum -y updateしていた為でした!
Elastic BeanstalkのTomcatには、固有のTomcat起動スクリプト/usr/sbin/tomcat7-elasticbeanstalkがあり、アップデートによりこれがデフォルトに戻されてしまうのが原因でした。
Beanstalkサーバのアップデートはしないのが無難! おとなしくAMIのアップデートを待つのが得策のようです。
よく訓練されたアップル信者、都元です。先週金曜日にハマった件があるのでシェアします。
Elastic Beanstalk environment with RDS instance
AWS Elastic Beanstalkにおいて、ManagementConsoleからenvironmentを作成する際に、同時にRDSのインスタンスを起動するオプションがあります。
便利ですね。しかし、データベースの接続情報(ホスト名、ポート番号、DB名等)は動的であるため、アプリケーション内にハードコーディングすることができなくなります。environmentをRDSと一緒に立ち上げただけで、アプリケーションとRDSがリンクする、つまり、アプリケーションがDB接続情報を取得できるような仕組みが必要です。あり〼。
このように立ち上げたRDSの接続情報は、環境変数から取得できます。各言語毎に取得手順が微妙に異なるため、詳細は以下のドキュメントを参照してください。
Javaにおける不具合
ここでは、以下Javaの例で話を進めます。ドキュメントによると、例えばこんな感じでJDBCの接続URLが手に入るそうです。
String dbName = System.getProperty("RDS_DB_NAME"); String userName = System.getProperty("RDS_USERNAME"); String password = System.getProperty("RDS_PASSWORD"); String hostname = System.getProperty("RDS_HOSTNAME"); String port = System.getProperty("RDS_PORT"); String jdbcUrl = "jdbc:mysql://" + hostname + ":" + port + "/" + dbName + "?user=" + userName + "&password=" + password;
このコードを実行した結果、jdbcUrlが以下のような文字列になるそうです。
jdbc:mysql://mydbinstance.abcdefghijkl.us-east-1.rds.amazonaws.com:3306/employees?user=sa&password=mypassword
現時点(2013/3/25)で、これが嘘なので注意してください、というのが本エントリの趣旨です。何も知らずにドキュメントを信じてアプリを実装し、DBに接続を試みると、以下のような例外が発生します。そこで思うわけです。なぜDNSの名前解決ができないのだ、と。
Caused by: java.net.UnknownHostException: "mydbinstance.abcdefghijkl.us-east-1.rds.amazonaws.com"
digで引いてみても問題ない、IPを直接ハードコーディングしてみると繋がる…。ハァ!? と思いながらも散々ハマること4時間。
謎解き編
ドキュメントによると、RDS_HOSTNAMEにはmydbinstance.abcdefghijkl.us-east-1.rds.amazonaws.comという文字列が入っているはずなのですが、実際には"mydbinstance.abcdefghijkl.us-east-1.rds.amazonaws.com"のように、ダブルクオートで囲まれた文字列が入っています。同様に、RDS_PORTには"3306"が入っています。
mydbinstance.abcdefghijkl.us-east-1.rds.amazonaws.comに繋ごうとした結果、DNSによるホスト名解決ができなかった時は、以下のような例外メッセージとなるはずです。ああ、ダブルクオートやん…。
Caused by: java.net.UnknownHostException: mydbinstance.abcdefghijkl.us-east-1.rds.amazonaws.com
しかし、なぜシステムプロパティの値の中にダブルクオートが入り込んでしまったのか、そこまでは追いきれませんでした。残念。従って、本現象は私の環境特有の事象の可能性もあります。
以上を一般的に発生する現象だとすれば、ドキュメント(仕様)と実装の不整合であるため、バグだと思います。AWSには通報済みですが、いつ直るのかは定かではありませんし、仕様側と実装側のどちらが修正されるのかも分かりません。しばらくはアプリケーション側のワークアラウンドで対処するしかないと思います。が、突然実装が修正されても落ちないように、アプリ側も対策しておく必要がありそうです。
と、いうわけで、本エントリがみなさまの大事な4時間をお守りできれば幸いでっす。続報があれば、追記や修正等していこうと思っています。
追記
2013-03-28: どうやら、他の環境ではダブルクオートで囲まれたりしないようです。AWSでも再現が確認出来なかったようで、かなり特殊ケースなのかもしれません。ただ、事象が再現しているコード及びenvironmentをAWSに提供したので、近々何らかの解決は見えると思います。